////////////////////////////////////////////////////////////
//	File:		"AL_Thread.h"
//	Author:		[AL] Anthony Lundquist
//	Created:	[AL] January 28, 2009
//	Purpose:	The Base thread Class
////////////////////////////////////////////////////////////
#include "AL_Thread.h"
#include <iostream>
#include <process.h>

////////////////////////////////////////////////////////////
//	Function:	cThreadProc
//	Created:	[AL] January 28, 2009
//	Purpose:	function passed into CreateThreadEx
//	In:			The member function to run
//	Out:		the return value for the thread
////////////////////////////////////////////////////////////
static unsigned __stdcall cThreadProc( LPVOID _pThis)
{
	return ((AL_Thread*)_pThis)->ThreadProc();
}

AL_Thread::AL_Thread() : m_hThreadHandle(NULL), m_dwThreadID(0), m_bIsRunning(false), m_bPaused(false), m_nExitCode(-1)
{
}

AL_Thread::~AL_Thread()
{
	// just in case
	End();
}

DWORD AL_Thread::ThreadProc(void)
{
	// initialize the thread
	Init();

	// if we paused the calling thread to start this one we unlock it
	if(m_slLock.IsLocked())
		m_slLock.Deactivate();

	while(IsRunning())
	{
		if(!m_bPaused)
			ThreadMain();
	}

	// shutdown the thread
	Shutdown();

	return 0;
}

void AL_Thread::Begin(bool _bLockUntilInit)
{
#if defined( _WIN32 )
		if( m_hThreadHandle )
			End();  // just to be safe.

		m_nExitCode = -1;

		// Start the thread.
		m_hThreadHandle = (HANDLE)_beginthreadex( NULL,
			0,
			&cThreadProc,
			(void*)this,
			0,
			&m_dwThreadID );

		m_bIsRunning = true;
		if( m_hThreadHandle == NULL )
		{
			// TODO: handle error stuff here >.>
			m_bIsRunning = false;
		}
		else
		{
			if(_bLockUntilInit)
				m_slLock.Activate();
		}
#endif
}

void AL_Thread::End()
{
#if defined( _WIN32 )
		if( m_hThreadHandle != NULL )
		{
			m_bIsRunning = false;
			WaitForSingleObject( m_hThreadHandle, INFINITE );
			DWORD ExitCode;
			GetExitCodeThread( m_hThreadHandle, &ExitCode );
			m_nExitCode = ExitCode;
			CloseHandle( m_hThreadHandle );
			m_hThreadHandle = NULL;
			printf("ThreadExitCode: %d\n",GetExitCode());
		}
#endif
}

bool AL_Thread::IsRunning()
{
	return m_bIsRunning;
}

DWORD AL_Thread::GetExitCode()
{
	return m_nExitCode;
}